package cn.schoolwow.util.domain.crypto.cipher.rsa;

import cn.schoolwow.quickflow.QuickFlow;
import cn.schoolwow.quickflow.QuickFlowBuilder;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.util.module.crypto.cipher.rsa.domain.RSACipherOption;
import cn.schoolwow.util.module.crypto.cipher.rsa.flow.GenerateKeyPairFlow;
import cn.schoolwow.util.module.crypto.cipher.rsa.flow.RSADecryptFlow;
import cn.schoolwow.util.module.crypto.cipher.rsa.flow.RSAEncryptFlow;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;

public class RSACipher {
    private RSACipherOption rsaCipherOption = new RSACipherOption();

    private QuickFlow quickFlow = QuickFlowBuilder.newInstance()
            .putContextThreadLocalInstanceData(rsaCipherOption);

    /**
     * 生成密钥对
     * @param rsaKeyPairType RSA算法密钥格式
     * */
    public static KeyPair generateKeyPair(RSAKeyPairType rsaKeyPairType){
        FlowContext flowContext = QuickFlowBuilder.startFlow(new GenerateKeyPairFlow())
                .putCurrentCompositeFlowData("keyLength", rsaKeyPairType.n)
                .execute();
        KeyPair keyPair = flowContext.checkInstanceData(KeyPair.class);
        return keyPair;
    }

    /**创建RSA算法对象*/
    public static RSACipher newCipher(){
        return new RSACipher();
    }

    /**指定明文或者密文*/
    public RSACipher data(String data){
        rsaCipherOption.data = data;
        return this;
    }

    /**指定密钥对*/
    public RSACipher keyPair(KeyPair keyPair){
        rsaCipherOption.publicKey = keyPair.getPublic();
        rsaCipherOption.privateKey = keyPair.getPrivate();
        return this;
    }

    /**指定公钥*/
    public RSACipher publicKey(PublicKey publicKey){
        rsaCipherOption.publicKey = publicKey;
        return this;
    }

    /**指定私钥*/
    public RSACipher privateKey(PrivateKey privateKey){
        rsaCipherOption.privateKey = privateKey;
        return this;
    }

    /**公钥加密*/
    public String encrypt(){
        FlowContext flowContext = quickFlow.startFlow(new RSAEncryptFlow())
                .execute();
        String encryptText = flowContext.getData("string", String.class);
        return encryptText;
    }

    /**私钥解密*/
    public String decrypt(){
        FlowContext flowContext = quickFlow.startFlow(new RSADecryptFlow())
                .execute();
        String plainText = flowContext.checkData("string", String.class);
        return plainText;
    }
}
